#ifndef HASH_H_
#define HASH_H_

#include "../ArchivoDeBloques/ArchivoDeBloques.h"
#include "Tabla.h"
#include "Bucket.h"
#include "BloquesLibres.h"
#include <iostream>
#include <vector>
#include <fstream>
#include <cstring>

using namespace std;


class Hash {

private:
	/*tabla de hash inicialmente tiene el mismo tamanio que la cantidad de buckets*/
	Tabla* tabla;
	/*nombre del archivo donde se va a almacenar la tabla de hash*/
	string narchivoTabla;
	/*archivo donde se almacenan los bloques que contienen los registros con las keys*/
	ArchivoDeBloques* archivo;

	/*es el archivo que cotiene los numeros de bloques libres, los guarda como registros,
	 * y se llama igual con la extension .libre*/
	BloquesLibres* archivoBLibres;

	/* Tamanio del bucket --en bytes porque los registros son de long variable?
	 * */
	unsigned int tamanioBucket;

	/* Cantidad de buckets que tiene el hash, al crearlo se le asigna el mismo valor
	 * al tamanio de la tabla de hash*/
	unsigned int cantidadBuckets;

public:
    /* Se crea el Hash
    * Se incializa el archivo de hash con un nombre y una cantidad de buckets.
	* Se inicializa la tabla con el tamanio igual a la cantidad de buckets
	* */
	Hash(string nombre, unsigned int tamanioBucket);

	virtual ~Hash();

	/* Inserta la key en el archivo y actualiza la tabla de hash
	* */
	bool insertar(Key key);

	/* Elimina la key del archivo y actualiza tabla
	 * */
	bool eliminar(Key key);

	/* busca el bucket donde estaria la clave y busca la clave ahi, si
	 * no esta devuelve false, si si esta intenta insertarla en el bucket, si se
	 * desborda el bucket, usa un bucket libre si hay sino crea uno nuevo y duplica la tabla de hash
	 *
	* */
	bool modificar(Key key);

	/* Busca la key, si la encuentra devuelve el valor
	* */
	string buscar(Key key);

	/* Devuelve el tamanio de los buckets (cantidad de registros que tiene)
	* */
	unsigned int obtenerTamanioBucket();

	/* Devuelve la cantidad de buckets que tiene la tabla 
	* */
	unsigned int obtenerCantidadBuckets();

	/*Muestra hash*/
	void mostrar();

	/*Devuelve true si la key existe*/
	bool existe(Key key);

};
#endif 
